package com.example.ywr.service.impl;

import com.example.ywr.common.PageParam;
import com.example.ywr.common.PageResult;
import com.example.ywr.entity.Product;
import com.example.ywr.repository.ProductRepository;
import com.example.ywr.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 商品服务实现类
 */
@Slf4j
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductRepository productRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Product add(Product product) {
        return productRepository.save(product);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Product update(Product product) {
        Optional<Product> optional = productRepository.findById(product.getId());
        if (optional.isPresent()) {
            Product existProduct = optional.get();
            // 更新商品信息
            existProduct.setName(product.getName());
            existProduct.setDescription(product.getDescription());
            existProduct.setPrice(product.getPrice());
            existProduct.setStock(product.getStock());
            existProduct.setImageUrl(product.getImageUrl());
            existProduct.setStatus(product.getStatus());
            existProduct.setCategoryId(product.getCategoryId());
            return productRepository.save(existProduct);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        Optional<Product> optional = productRepository.findById(id);
        if (optional.isPresent()) {
            Product product = optional.get();
            product.setIsDeleted(true);
            productRepository.save(product);
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDelete(List<Long> ids) {
        List<Product> products = productRepository.findAllById(ids);
        if (!products.isEmpty()) {
            products.forEach(product -> product.setIsDeleted(true));
            productRepository.saveAll(products);
            return true;
        }
        return false;
    }

    @Override
    public Product getById(Long id) {
        Optional<Product> optional = productRepository.findById(id);
        return optional.orElse(null);
    }

    @Override
    public PageResult<Product> list(PageParam pageParam) {
        Sort sort = Sort.by(Sort.Direction.fromString(pageParam.getOrderDirection()), 
                pageParam.getOrderBy() != null ? pageParam.getOrderBy() : "id");
        Pageable pageable = PageRequest.of(pageParam.getPageNum() - 1, pageParam.getPageSize(), sort);
        Page<Product> page = productRepository.findAll(pageable);
        return PageResult.fromPage(page);
    }

    @Override
    public PageResult<Product> listByName(String name, PageParam pageParam) {
        Sort sort = Sort.by(Sort.Direction.fromString(pageParam.getOrderDirection()), 
                pageParam.getOrderBy() != null ? pageParam.getOrderBy() : "id");
        Pageable pageable = PageRequest.of(pageParam.getPageNum() - 1, pageParam.getPageSize(), sort);
        Page<Product> page = productRepository.findByNameContainingAndIsDeletedFalse(name, pageable);
        return PageResult.fromPage(page);
    }

    @Override
    public PageResult<Product> listByCategoryId(Long categoryId, PageParam pageParam) {
        Sort sort = Sort.by(Sort.Direction.fromString(pageParam.getOrderDirection()), 
                pageParam.getOrderBy() != null ? pageParam.getOrderBy() : "id");
        Pageable pageable = PageRequest.of(pageParam.getPageNum() - 1, pageParam.getPageSize(), sort);
        Page<Product> page = productRepository.findByCategoryIdAndIsDeletedFalse(categoryId, pageable);
        return PageResult.fromPage(page);
    }

    @Override
    public PageResult<Product> listByStatus(Integer status, PageParam pageParam) {
        Sort sort = Sort.by(Sort.Direction.fromString(pageParam.getOrderDirection()), 
                pageParam.getOrderBy() != null ? pageParam.getOrderBy() : "id");
        Pageable pageable = PageRequest.of(pageParam.getPageNum() - 1, pageParam.getPageSize(), sort);
        Page<Product> page = productRepository.findByStatusAndIsDeletedFalse(status, pageable);
        return PageResult.fromPage(page);
    }

    @Override
    public PageResult<Product> listByCategoryIdAndStatus(Long categoryId, Integer status, PageParam pageParam) {
        Sort sort = Sort.by(Sort.Direction.fromString(pageParam.getOrderDirection()), 
                pageParam.getOrderBy() != null ? pageParam.getOrderBy() : "id");
        Pageable pageable = PageRequest.of(pageParam.getPageNum() - 1, pageParam.getPageSize(), sort);
        Page<Product> page = productRepository.findByCategoryIdAndStatusAndIsDeletedFalse(categoryId, status, pageable);
        return PageResult.fromPage(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long id, Integer status) {
        int rows = productRepository.updateStatus(id, status);
        return rows > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateStatus(List<Long> ids, Integer status) {
        int rows = productRepository.batchUpdateStatus(ids, status);
        return rows > 0;
    }
}